package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.ExamRecord;
import com.atguigu.exam.entity.Paper;
import com.atguigu.exam.entity.PaperQuestion;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.mapper.PaperMapper;
import com.atguigu.exam.mapper.PaperQuestionMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.PaperQuestionService;
import com.atguigu.exam.service.PaperService;
import com.atguigu.exam.vo.PaperVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 试卷服务实现类
 */
@Slf4j
@Service
@Transactional
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {
    @Autowired
    private PaperQuestionMapper paperquestionMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private PaperQuestionService paperQuestionService;

    @Autowired
    private ExamRecordMapper examRecordMapper;

    @Override
    public Paper getPaperDetailsById(Integer id) {
        Paper paper = baseMapper.selectById(id);
//        List<PaperQuestion> paperQuestions = paperquestionMapper.selectList(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId, id));
//        List<Long> questionIds = paperQuestions.stream().map(PaperQuestion::getQuestionId).collect(Collectors.toList());
//        ArrayList<Question> list = new ArrayList<>();
//        questionIds.forEach(questionId -> {
//            Question questionDetailById = questionMapper.getQuestionDetailById(questionId);
//            list.add(questionDetailById);
//        });

        List<Question> list = questionMapper.questionListByPaperId(id);
        //按照选择判断简答排序
        list.sort(Comparator.comparing(Question::getType));
        paper.setQuestions(list);
        return paper;
    }

    @Override
    public Paper createPaper(PaperVo paperVo) {
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, paperVo.getName()));
        if(exists){
            throw new ExamException(1999,"该试卷已经存在");
        }
        Paper paper = new Paper();
        BeanUtils.copyProperties(paperVo,paper);
        paper.setStatus("DRAFT");
        Map<Long, BigDecimal> questions = paperVo.getQuestions();
        paper.setQuestionCount(questions.size());

        BigDecimal totalScore = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(totalScore);
        baseMapper.insert(paper);

        List<PaperQuestion> collect = questions.entrySet().stream().map(entry -> new PaperQuestion(Math.toIntExact(paper.getId()), entry.getKey(), entry.getValue())).collect(Collectors.toList());
        paperQuestionService.saveBatch(collect);
        return paper;
    }

    @Override
    public Paper updatePaper(Integer id, PaperVo paperVo) {
        Paper paper = baseMapper.selectById(id);
        if("PUBLISHED".equals(paper.getStatus())){
            throw new ExamException(1008,"试卷发布状态不可以修改");
        }
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, paperVo.getName()).ne(Paper::getId, id));
        if(exists){
            throw new ExamException(1009,"试卷已经存在");
        }

        BeanUtils.copyProperties(paperVo,paper);
        paper.setUpdateTime(new Date());

        Map<Long, BigDecimal> questions = paperVo.getQuestions();
        paper.setQuestionCount(questions.size());

        BigDecimal totalScore = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(totalScore);
        baseMapper.updateById(paper);

        paperquestionMapper.delete(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId,id));

        List<PaperQuestion> collect = questions.entrySet().stream().map(entry -> new PaperQuestion(Math.toIntExact(paper.getId()), entry.getKey(), entry.getValue())).collect(Collectors.toList());
        paperQuestionService.saveBatch(collect);
        return paper;
    }

    @Override
    public void updatePaperStatus(Integer id, String status) {
        Long count = examRecordMapper.selectCount(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getExamId, id).eq(ExamRecord::getStatus, "进行中"));
        if(count>0){
            throw new ExamException(1004,"试卷正在被考试,不能更新为草稿");
        }
        baseMapper.update(null,new LambdaUpdateWrapper<Paper>().eq(Paper::getId,id).set(Paper::getStatus,status));

    }

    @Override
    public void deletePaperById(Integer id) {
        Long count = examRecordMapper.selectCount(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getExamId, id).eq(ExamRecord::getStatus, "进行中"));
        if(count>0){
            throw new ExamException(1005,"试卷正在被考试,不能删除");
        }

        baseMapper.deleteById(id);
        paperquestionMapper.delete(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId,id));
    }
}